﻿using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using SMSGateway.Threading;
using System.Web.Mail;
using System.Configuration;
//using ProcessesSMS.Base;
namespace ProcessesSMS
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class FormProcesses : System.Windows.Forms.Form
	{
		private string connstr =ConfigurationSettings.AppSettings["SMSConnStr"];
		private string SMSConnStrResult =ConfigurationSettings.AppSettings[""];				
		private WorkQueue MOWork;
		private XOSO_WAIT xs_wait = new XOSO_WAIT();
		private int[] MOstats;
		private DateTime nextRefreshTime;
		private TimeSpan refreshInterval;
		private SqlConnection MOConn;
		private System.Windows.Forms.ContextMenu fsmMenu;
		private System.Windows.Forms.MenuItem mnuPauseMO;
		private System.Windows.Forms.MenuItem mnuResumeMO;
		private System.Windows.Forms.Button cmdRun;
		private System.Windows.Forms.Timer MOTimer;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.TextBox MOCompleteCount;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.TextBox MOErrorCount;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.TextBox MORunningCount;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.TextBox MOWaitCount;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.TextBox MOQueueCount;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.TextBox txtLog;
        private System.Windows.Forms.Timer MLTimer;
		private System.ComponentModel.IContainer components;

		public FormProcesses()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
			ConfigSettings.LoadConfig();
			
			nextRefreshTime = DateTime.Now;
			refreshInterval = TimeSpan.FromSeconds(0.20);

			MOstats = new int[6];
			
			
			MOWork = new WorkQueue();
			((WorkThreadPool)MOWork.WorkerPool).MaxThreads=ConfigApp.maxThread;
			((WorkThreadPool)MOWork.WorkerPool).MinThreads=ConfigApp.minThread;
			MOWork.ConcurrentLimit = ConfigApp.ConcurrentLimit;
			MOWork.WorkerException += new ResourceExceptionEventHandler(MOWork_WorkerException);
			MOWork.ChangedWorkItemState += new ChangedWorkItemStateEventHandler(MOWork_ChangedWorkItemState);
			MOWork.FailedWorkItem +=new WorkItemEventHandler(MOWork_FailedWorkItem);
			MOWork.AllWorkCompleted+=new EventHandler(MOWork_AllWorkCompleted);
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            this.fsmMenu = new System.Windows.Forms.ContextMenu();
            this.mnuPauseMO = new System.Windows.Forms.MenuItem();
            this.mnuResumeMO = new System.Windows.Forms.MenuItem();
            this.cmdRun = new System.Windows.Forms.Button();
            this.MOTimer = new System.Windows.Forms.Timer(this.components);
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.MOCompleteCount = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.MOErrorCount = new System.Windows.Forms.TextBox();
            this.MOWaitCount = new System.Windows.Forms.TextBox();
            this.MORunningCount = new System.Windows.Forms.TextBox();
            this.MOQueueCount = new System.Windows.Forms.TextBox();
            this.txtLog = new System.Windows.Forms.TextBox();
            this.MLTimer = new System.Windows.Forms.Timer(this.components);
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // fsmMenu
            // 
            this.fsmMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuPauseMO,
            this.mnuResumeMO});
            // 
            // mnuPauseMO
            // 
            this.mnuPauseMO.Index = 0;
            this.mnuPauseMO.Text = "";
            // 
            // mnuResumeMO
            // 
            this.mnuResumeMO.Index = 1;
            this.mnuResumeMO.Text = "";
            // 
            // cmdRun
            // 
            this.cmdRun.Location = new System.Drawing.Point(216, 177);
            this.cmdRun.Name = "cmdRun";
            this.cmdRun.Size = new System.Drawing.Size(75, 23);
            this.cmdRun.TabIndex = 2;
            this.cmdRun.Text = "Start";
            this.cmdRun.Click += new System.EventHandler(this.cmdRun_Click);
            // 
            // MOTimer
            // 
            this.MOTimer.Tick += new System.EventHandler(this.MOTimer_Tick);
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.MOCompleteCount);
            this.groupBox1.Controls.Add(this.label1);
            this.groupBox1.Controls.Add(this.label2);
            this.groupBox1.Controls.Add(this.label3);
            this.groupBox1.Controls.Add(this.label4);
            this.groupBox1.Controls.Add(this.label5);
            this.groupBox1.Controls.Add(this.MOErrorCount);
            this.groupBox1.Controls.Add(this.MOWaitCount);
            this.groupBox1.Controls.Add(this.MORunningCount);
            this.groupBox1.Controls.Add(this.MOQueueCount);
            this.groupBox1.Location = new System.Drawing.Point(10, 10);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(200, 190);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "SMS MO";
            // 
            // MOCompleteCount
            // 
            this.MOCompleteCount.Enabled = false;
            this.MOCompleteCount.Location = new System.Drawing.Point(80, 152);
            this.MOCompleteCount.Name = "MOCompleteCount";
            this.MOCompleteCount.Size = new System.Drawing.Size(100, 20);
            this.MOCompleteCount.TabIndex = 0;
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(64, 23);
            this.label1.TabIndex = 9;
            this.label1.Text = "Queue MO";
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(8, 56);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(64, 23);
            this.label2.TabIndex = 7;
            this.label2.Text = "Waiting";
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(8, 88);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(64, 23);
            this.label3.TabIndex = 5;
            this.label3.Text = "Running";
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(8, 120);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(64, 23);
            this.label4.TabIndex = 3;
            this.label4.Text = "Failed";
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(8, 152);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(64, 23);
            this.label5.TabIndex = 1;
            this.label5.Text = "Completed";
            // 
            // MOErrorCount
            // 
            this.MOErrorCount.Enabled = false;
            this.MOErrorCount.Location = new System.Drawing.Point(80, 120);
            this.MOErrorCount.Name = "MOErrorCount";
            this.MOErrorCount.Size = new System.Drawing.Size(100, 20);
            this.MOErrorCount.TabIndex = 2;
            // 
            // MOWaitCount
            // 
            this.MOWaitCount.Enabled = false;
            this.MOWaitCount.Location = new System.Drawing.Point(80, 56);
            this.MOWaitCount.Name = "MOWaitCount";
            this.MOWaitCount.Size = new System.Drawing.Size(100, 20);
            this.MOWaitCount.TabIndex = 6;
            // 
            // MORunningCount
            // 
            this.MORunningCount.Enabled = false;
            this.MORunningCount.Location = new System.Drawing.Point(80, 88);
            this.MORunningCount.Name = "MORunningCount";
            this.MORunningCount.Size = new System.Drawing.Size(100, 20);
            this.MORunningCount.TabIndex = 4;
            // 
            // MOQueueCount
            // 
            this.MOQueueCount.Enabled = false;
            this.MOQueueCount.Location = new System.Drawing.Point(80, 24);
            this.MOQueueCount.Name = "MOQueueCount";
            this.MOQueueCount.Size = new System.Drawing.Size(100, 20);
            this.MOQueueCount.TabIndex = 8;
            // 
            // txtLog
            // 
            this.txtLog.Location = new System.Drawing.Point(8, 216);
            this.txtLog.Multiline = true;
            this.txtLog.Name = "txtLog";
            this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtLog.Size = new System.Drawing.Size(292, 144);
            this.txtLog.TabIndex = 1;
            // 
            // FormProcesses
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(311, 376);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.txtLog);
            this.Controls.Add(this.cmdRun);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Name = "FormProcesses";
            this.Load += new System.EventHandler(this.FormProcesses_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		/// 
		[STAThread]
		static void Main() 
		{
            Application.Run(new FormProcesses());
            //Application.Run(new FormTestCode());
		}

		public void LogLine(string msg)
		{
			lock (txtLog)
			{
				if (txtLog.Text.Length > 0)
					txtLog.Text += "\r\n"	+ msg;
				else
					txtLog.Text = msg;
			}
		}
		#region Work Queue Event
		private void MOWork_ChangedWorkItemState(object sender, ChangedWorkItemStateEventArgs e)
		{
			lock (MOstats)
			{
				if (e.PreviousState!=WorkItemState.Failing)
				{
					MOstats[(int) e.PreviousState] -= 1;
					MOstats[(int) e.WorkItem.State] += 1;
				}
			}

			if (!mnuPauseMO.Enabled || DateTime.Now > nextRefreshTime)
			{
				RefreshMOCounts();
				nextRefreshTime = DateTime.Now + refreshInterval;
			}
		}
		private void MOWork_WorkerException(object sender, ResourceExceptionEventArgs e)
		{
			LogLine(e.Exception.Message); 
		}
		private void MOWork_FailedWorkItem(object sender,WorkItemEventArgs e)
		{
			LogLine(e.WorkItem.FailedException.Message);
		}
		private void MOWork_AllWorkCompleted(object sender, EventArgs e)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new EventHandler(MOWork_AllWorkCompleted), new object[] {sender, e});
			}
			else
			{
				RefreshMOCounts();
				lock(MOstats)
				{
					MOstats[(int)WorkItemState.Created] = 0;
					MOstats[(int)WorkItemState.Queued] = 0;
					MOstats[(int)WorkItemState.Scheduled] = 0;
					MOstats[(int)WorkItemState.Running] = 0;
				}
			}
		}
		
		// Refresh
		private void RefreshMOCounts()
		{
			if (this.InvokeRequired)
			{
				MethodInvoker mi = new MethodInvoker(RefreshMOCounts);
				this.BeginInvoke(mi);
			}
			else
			{
				lock (MOCompleteCount)
				{
					MOCompleteCount.Text = MOstats[(int) WorkItemState.Completed].ToString("N0");
				}
				lock (MOErrorCount)
				{
					MOErrorCount.Text = MOstats[(int) WorkItemState.Failing].ToString("N0");
				}
				lock (MOQueueCount)
				{
					MOQueueCount.Text = MOstats[(int) WorkItemState.Queued].ToString("N0");
				}
				lock (MORunningCount)
				{
					MORunningCount.Text = MOstats[(int) WorkItemState.Running].ToString("N0");
				}
				lock (MOWaitCount)
				{
					MOWaitCount.Text = MOstats[(int) WorkItemState.Scheduled].ToString("N0");
				}
			}
		}
		#endregion
        private void LoadMOQueue()
        {
            if (MOConn.State == ConnectionState.Closed)
            {
                try
                {
                    MOConn.Open();
                }
                catch
                {
                    if (MOConn.State == ConnectionState.Open)
                    {
                        MOConn.Close();
                    }
                    LogLine("Không kết nối được với Database");
                    return;
                }
            }
            SqlCommand oCommand = null;
            try
            {
                oCommand =new SqlCommand("GW_GetSMSMO", MOConn);
                MOConn.Close();
            }
            catch
            {
                if (MOConn.State == ConnectionState.Open)
                {
                    MOConn.Close();
                }
                LogLine("Truy vấn quá thời gian cho phép");
            }
            oCommand.CommandType = CommandType.StoredProcedure;
            SqlDataAdapter oAdapter = new SqlDataAdapter();
            oAdapter.SelectCommand = oCommand;
            DataSet oDataSet = new DataSet();
            oAdapter.Fill(oDataSet);

            if (oDataSet.Tables[0].Rows.Count > 0)
            {
                lock (MOWork)
                {
                    for (int i = 0; i < oDataSet.Tables[0].Rows.Count; i++)
                    {
                        //MO_ID,UserID,ServiceID,CommandCode,Message,RequestID
                        int MO_ID = 0;
                        try
                        {
                            //MessageBox.Show("command");
                            MO_ID = Convert.ToInt32(oDataSet.Tables[0].Rows[i]["MO_ID"]);
                            string UserID = oDataSet.Tables[0].Rows[i]["UserID"].ToString();
                            string ServiceID = oDataSet.Tables[0].Rows[i]["ServiceID"].ToString();
                            string CommandCode = oDataSet.Tables[0].Rows[i]["CommandCode"].ToString();
                            string Message = oDataSet.Tables[0].Rows[i]["Message"].ToString();
                            int RequestID = Convert.ToInt32(oDataSet.Tables[0].Rows[i]["RequestID"]);
                            DateTime RequestTime = Convert.ToDateTime(oDataSet.Tables[0].Rows[i]["RequestTime"]);
                            //MessageBox.Show("command:" + Message);							
                            MOWork.Add(new MOWorkItem(MO_ID, UserID, ServiceID, CommandCode, Message, RequestID, RequestTime));
                        }
                        catch (Exception ex)
                        {
                            LogLine("Push MO Queue Error: [" + MO_ID + "] " + ex.Message);
                        }
                    }
                }
            }
        }


		private void LoadMLQueue(string strStore,bool flag)
		{
			if (MOConn.State==ConnectionState.Closed)
			{
				try
				{
					MOConn.Open();
				}
				catch
				{
					LogLine("Không kết nối được với Database");
					return;
				}
			}
			SqlCommand oCommand = new SqlCommand(strStore,MOConn);
			oCommand.CommandType=CommandType.StoredProcedure;
			if(flag)
			{
				oCommand.Parameters.Add( new SqlParameter("@Day",SqlDbType.NVarChar));
				oCommand.Parameters.Add( new SqlParameter("@Month",SqlDbType.NVarChar));
				oCommand.Parameters["@Day"].Value = DateTime.Now.Day.ToString();
				oCommand.Parameters["@Month"].Value = DateTime.Now.Month.ToString();
			}
			SqlDataAdapter oAdapter= new SqlDataAdapter();			
			oAdapter.SelectCommand=oCommand;
			DataSet oDataSet = new DataSet(); 
			oAdapter.Fill(oDataSet);
			
			if (oDataSet.Tables[0].Rows.Count>0)
			{
				lock(MOWork)
				{
					for(int i=0;i<oDataSet.Tables[0].Rows.Count;i++)
					{						
						try
						{							
							int MO_ID=Convert.ToInt32(oDataSet.Tables[0].Rows[i]["MO_ID"]);
							string UserID = oDataSet.Tables[0].Rows[i]["UserID"].ToString();
							string ServiceID = oDataSet.Tables[0].Rows[i]["ServiceID"].ToString();
							string CommandCode = oDataSet.Tables[0].Rows[i]["CommandCode"].ToString();
							string Message = oDataSet.Tables[0].Rows[i]["Message"].ToString();
							int RequestID = Convert.ToInt32(oDataSet.Tables[0].Rows[i]["RequestID"]);
							DateTime RequestTime = Convert.ToDateTime(oDataSet.Tables[0].Rows[i]["RequestTime"]);
							int Count = Convert.ToInt32(oDataSet.Tables[0].Rows[i]["Number"]);
							MOWork.Add(new MOWorkItem(MO_ID,UserID,ServiceID,CommandCode,Message,RequestID,RequestTime,Count));							
						}
						catch(Exception ex)
						{
							LogLine("Push MO Queue Error: " + ex.Message);
						}
					}
				}
			}
		}


		private void cmdRun_Click(object sender, System.EventArgs e)
		{			
			if (cmdRun.Text.ToLower()=="start")
			{
				MOConn = new SqlConnection(ConfigApp.ConnStr);
				try
				{
					MOConn.Open();
				}
				catch
				{
					LogLine("Không kết nối được với Database");
				}
				finally
				{
					cmdRun.Text="Stop";
					MOTimer.Start();
					//MLTimer.Start();
					//ACTIVEtimer.Start();
					//SendMsgCHO_TTtimer.Start();
				}
			}
			else
			{
				MOTimer.Stop();
				//MLTimer.Stop();
				//ACTIVEtimer.Stop();
				//SendMsgCHO_TTtimer.Stop();
				cmdRun.Text="Start";
				if (MOConn.State==ConnectionState.Open)
				{
					MOConn.Close();
				}
			}		
			
		}

		private void MOTimer_Tick(object sender, System.EventArgs e)
		{
			MOTimer.Stop();
			try
			{
				LoadMOQueue();				
			}
			catch(Exception ex)
			{
				LogLine("Load MO Error:" + ex.Message);
			}
			MOTimer.Start();
		}
        
		private void FormProcesses_Load(object sender, System.EventArgs e)
		{
			this.Text=ConfigSettings.ReadSetting("AppTitle");			
			if (cmdRun.Text.ToLower() == "start")
			{
				cmdRun_Click(sender,e);
			}
		}		

		private bool checkIsDate(string txDate)
		{			 
			Int16 day,month;
			day = Int16.Parse(txDate.Substring(0,2));
			month = Int16.Parse(txDate.Substring(2));
			if (month>12) return false;
			if (month ==1 || month ==3 || month == 5 || month ==7 || month ==8 || month == 10 || month ==12)
			{if (day>31) return false;}
			else if (month == 2)
			{if (day>29) return false;}
			else if (day>30) return false;
			return true;
		}
        /*
        private void ACTIVEtimer_Tick(object sender, System.EventArgs e)
        {
            try
            {
                //chi quet khi textbox=0, tuc la khi tin nhan yeu cau da duoc gui
                if (int.Parse(txtactiveCHO.Text) == 0)
                {
                    string[] strmess = xs_wait.GetActiveCHO().Split(',');
                    txtactiveCHO.Text = strmess[0];
                    txtprovinceCHO.Text = strmess[1];
                }
                if (int.Parse(txtactiveTT.Text) == 0)
                {
                    string[] strmessTT = xs_wait.GetActiveTT().Split(',');
                    txtactiveTT.Text = strmessTT[0];
                    txtprovinceTT.Text = strmessTT[1];
                }
            }
            catch(Exception ex)
            {
                LogLine("Load XOSO ACTIVE Error:" + ex.Message);
            }
        }

        private void SendMsgCHO_TTtimer_Tick(object sender, System.EventArgs e)
        {
            //XOSO_WAIT xs_wait= new XOSO_WAIT();
            //chi gui khi textbox=1, tuc la khi co yeu cau gui tin nhan thi gui tin nhan,bao lai da gui xong
            try
            {
                if (int.Parse(txtactiveCHO.Text) == 1)
                {
                    xs_wait.SendSMS_WAITMsgCHO(txtprovinceCHO.Text.Trim());
                    xs_wait.ResetActiveCHO();
                    txtactiveCHO.Text = "0";
                    txtprovinceCHO.Text = "";
                }

                if (int.Parse(txtactiveTT.Text) == 1)
                {

                    xs_wait.SendSMS_WAITMsgTT();
                    xs_wait.ResetActiveTT();
                    txtactiveTT.Text = "0";
                    txtprovinceTT.Text = "";
                }
            }
            catch(Exception ex)
            {
                LogLine("Load XOSO CHO Error:" + ex.Message);
            }

        }
       
        private void MLTimer_Tick(object sender, EventArgs e)
        {

        }
       */
    }
}
